import { IPublicTypeJSExpression, IPublicTypeNodeData } from '@alilc/lowcode-types';
import { HandlerSet, IScope, NodeGeneratorConfig, PIECE_TYPE } from '../types';
import { generateExpression, generateFunction } from './jsExpression';
import { transformJsExpr } from './core/jsx/handlers/transformJsExpression';
import { transformThis2Context } from './core/jsx/handlers/transformThis2Context';
import { generateCompositeType } from './compositeType';
import { Scope } from './Scope';
import { createReactNodeGenerator } from './nodeToJsx';

const __log: any = function () {};

const nodeTypeMapping = {
  Div: 'View',
  Component: 'React.Fragment',
  Page: 'Page',
  Block: 'React.Fragment',
};
const tolerateEvalErrors = {} as Record<string, string>;

const customHandlers: HandlerSet<string> = {
  expression(input: IPublicTypeJSExpression, scope: IScope, config) {
    // 检查表达式中是否包含循环变量引用
    const bindings = scope.bindings?.getAllBindings() || [];
    const exprValue = input.value;

    // 检查是否包含循环变量引用
    const hasLoopVars = bindings.some((binding) => {
      const pattern = new RegExp(`\\b(this\\.)?${binding}\\b`, 'g');
      return pattern.test(exprValue);
    });

    // 如果包含循环变量引用，需要保留this引用
    const preserveThisForLoopVars = false;

    return transformJsExpr(generateExpression(input, scope), scope, {
      dontWrapEval: !config?.tolerateEvalErrors,
      dontTransformThis2ContextAtRootScope: true,
      forceTransformThis: false,
      preserveThisForLoopVars,
    });
  },
  function(
    input,
    scope: IScope,
    config: {
      tolerateEvalErrors?: boolean;
      loopItemName?: string;
      loopIndexName?: string;
      attrName?: string;
    } = {},
  ) {
    // 获取函数值
    const functionValue = input.value || '';

    __log('【函数处理器】原始函数值:', functionValue);

    // 特殊处理：检查是否是事件处理函数（以on开头的属性）
    const isEventHandler = config?.attrName && config.attrName.startsWith('on');
    __log('【函数处理器】是否是事件处理函数:', isEventHandler, '属性名:', config?.attrName);

    // 检查函数是否已经是箭头函数（使用正则表达式正确匹配箭头函数）
    const isArrowFunction = /^\s*(?:async\s+)?(\(.*?\)|[^=>()\s]+)\s*=>/s.test(
      functionValue.trim(),
    );
    __log('【函数处理器】是否已经是箭头函数:', isArrowFunction);

    // 检查函数是否是普通函数定义
    const isRegularFunction = functionValue.trim().startsWith('function');
    __log('【函数处理器】是否是普通函数定义:', isRegularFunction);

    // 特殊处理：检查是否是特定模式的函数
    const isSpecialPattern =
      functionValue.includes('this.') ||
      functionValue.includes('apply') ||
      functionValue.includes('arguments');
    __log('【函数处理器】是否是特殊模式的函数:', isSpecialPattern);

    // 检查函数值是否包含apply和arguments，这通常表示它是一个需要特殊处理的绑定表达式
    const isBindExpr = functionValue.includes('.apply(this,Array.prototype.slice.call(arguments)');
    __log('【函数处理器】是否是绑定表达式:', isBindExpr);

    // 检查是否是异步函数
    const isAsync = functionValue.trim().startsWith('async');
    __log('【函数处理器】是否是异步函数:', isAsync);

    // 检查函数中是否包含循环变量引用
    const bindings = scope.bindings?.getAllBindings() || [];
    const loopVars = bindings.filter((binding) => {
      const pattern = new RegExp(`\\bthis\\.${binding}\\b`, 'g');
      return pattern.test(functionValue);
    });
    __log('【函数处理器】检测到的循环变量:', loopVars);

    // 从config中获取循环变量名称，如果没有从函数中检测到的循环变量，则使用config中的
    const loopItemName = loopVars.length > 0 ? loopVars[0] : config?.loopItemName;
    const loopIndexName = loopVars.length > 1 ? loopVars[1] : config?.loopIndexName;
    __log('【函数处理器】使用的循环变量名称:', { loopItemName, loopIndexName });

    // 如果函数中包含this引用，需要转换为箭头函数
    const hasThisReference = functionValue.includes('this.');
    __log('【函数处理器】是否包含this引用:', hasThisReference);

    // 始终使用箭头函数，无论是否有循环变量引用或this引用
    const shouldUseArrow = true;
    __log('【函数处理器】是否应该使用箭头函数:', shouldUseArrow);

    // 如果是事件处理函数且包含this引用，强制转换为箭头函数
    if (isEventHandler && hasThisReference) {
      __log('【函数处理器】事件处理函数包含this引用，强制转换为箭头函数');
      const result = generateFunction(
        {
          type: 'JSFunction',
          value: functionValue,
        },
        scope,
        {
          isBindExpr,
          isArrow: true, // 强制使用箭头函数
          loopItemName,
          loopIndexName,
        },
      );
      __log('【函数处理器】转换后的事件处理函数:', result);
      return result;
    }

    // 如果是特殊模式的函数，需要特殊处理
    if (isSpecialPattern) {
      __log('【函数处理器】处理特殊模式的函数');

      // 如果函数已经是箭头函数，但包含this引用，需要保留this引用
      if (isArrowFunction && hasThisReference) {
        __log('【函数处理器】函数已经是箭头函数，但包含this引用，保留this引用');

        // 处理循环变量引用
        let processedValue = functionValue;
        bindings.forEach((binding) => {
          if (processedValue.includes(`this.${binding}`)) {
            __log(`【函数处理器】替换 this.${binding} 为 ${binding}`);
            processedValue = processedValue.replace(new RegExp(`this\\.${binding}`, 'g'), binding);
          }
        });

        __log('【函数处理器】处理后的函数:', processedValue);
        return processedValue;
      } else if (hasThisReference) {
        // 如果函数不是箭头函数，但包含this引用，需要转换为箭头函数
        __log('【函数处理器】函数不是箭头函数，但包含this引用，转换为箭头函数');
        const result = generateFunction(
          {
            type: 'JSFunction',
            value: functionValue,
          },
          scope,
          {
            isBindExpr,
            isArrow: true, // 强制使用箭头函数
            loopItemName,
            loopIndexName,
          },
        );
        __log('【函数处理器】转换后的函数:', result);
        return result;
      }
    }

    // 如果已经是箭头函数，直接使用原始值
    if (isArrowFunction) {
      __log('【函数处理器】函数已经是箭头函数，直接处理循环变量引用');
      // 仍然需要处理循环变量引用
      const result = generateFunction(
        {
          type: 'JSFunction',
          value: functionValue,
        },
        scope,
        {
          isBindExpr,
          isArrow: shouldUseArrow,
          loopItemName,
          loopIndexName,
        },
      );
      __log('【函数处理器】处理后的箭头函数:', result);
      return result;
    }

    // 如果是普通函数定义，需要转换为箭头函数
    if (isRegularFunction) {
      __log('【函数处理器】函数是普通函数定义，转换为箭头函数');
      const result = generateFunction(
        {
          type: 'JSFunction',
          value: functionValue,
        },
        scope,
        {
          isBindExpr,
          isArrow: shouldUseArrow,
          loopItemName,
          loopIndexName,
        },
      );
      __log('【函数处理器】转换后的函数:', result);
      return result;
    }

    // 如果是异步函数，确保正确处理
    if (isAsync) {
      __log('【函数处理器】处理异步函数');
      const result = generateFunction(
        {
          type: 'JSFunction',
          value: functionValue,
        },
        scope,
        {
          isBindExpr,
          isArrow: shouldUseArrow,
          loopItemName,
          loopIndexName,
        },
      );
      __log('【函数处理器】处理后的异步函数:', result);
      return result;
    }

    const result = generateFunction(
      {
        type: 'JSFunction',
        value: functionValue,
      },
      scope,
      {
        isBindExpr,
        isArrow: shouldUseArrow, // 始终使用箭头函数
        loopItemName,
        loopIndexName,
      },
    );
    __log('【函数处理器】转换后的函数:', result);
    return result;
  },
};

const generatorPlugins: NodeGeneratorConfig = {
  handlers: customHandlers,
  tagMapping: (v) => nodeTypeMapping[v] || v,
  tolerateEvalErrors: false,
};

// if (next.contextData.useRefApi) {
generatorPlugins.attrPlugins = [
  (attrData, scope, pluginCfg, nextFunc) => {
    if (attrData.attrName === 'ref') {
      return [
        {
          name: attrData.attrName,
          // value: `this._refsManager.linkRef('${attrData.attrValue}')`,
          value: `'${attrData.attrValue}'`,
          type: PIECE_TYPE.ATTR,
        },
      ];
    }

    return nextFunc ? nextFunc(attrData, scope, pluginCfg) : [];
  },
];
// }

export const reactNodeGenerator = createReactNodeGenerator(generatorPlugins);

export const scope: IScope = Scope.createRootScope();
